
package com.insigma.business.qrcode.soldier._provider.impl;



import cn.hutool.core.date.DateUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.insigma.business.qrcode.common.dto.ErrorCodeEnum;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;


import com.insigma.business.qrcode.common.service.GovOrgService;
import com.insigma.business.qrcode.common.template.BasePagingResponse;
import com.insigma.business.qrcode.common.util.BizCheckUtil;
import com.insigma.business.qrcode.common.util.BizException;
import com.insigma.business.qrcode.common.util.ResponseUtils;
import com.insigma.business.qrcode.common.vo.*;
import com.insigma.business.qrcode.soldier._provider.GovEmployeeProvider;
import com.insigma.business.qrcode.soldier._provider.PlacementPositionInfoProvider;
import com.insigma.business.qrcode.soldier._provider.PlacementSoldierInfoProvider;
import com.insigma.business.qrcode.soldier.dto.*;
import com.insigma.business.qrcode.soldier.dto.gov.BaseProviderImpl;
import com.insigma.business.qrcode.common.template.area.ServiceCallback;
import com.insigma.business.qrcode.common.template.area.ScenarioCodeEnum;
import com.insigma.business.qrcode.soldier.entity.*;
import com.insigma.business.qrcode.soldier.request.*;
import com.insigma.business.qrcode.soldier.service.*;
import com.insigma.business.qrcode.common.converter.PlacementPositionInfoProviderConverter;
import com.insigma.business.qrcode.common.converter.PlacementSoldierAspirationProviderConverter;
import com.insigma.business.qrcode.common.converter.PlacementSoldierAspirationResultProviderConverter;
import com.insigma.business.qrcode.common.converter.PlacementSoldierInfoProviderConverter;
import com.insigma.business.qrcode.soldier.util.MiniCacheUtils;
import com.insigma.business.qrcode.soldier.util.RequestSetUtils;
import com.insigma.business.qrcode.soldier.util.TwoLevelCheckUtils;
import com.insigma.business.qrcode.welfare.util.PasswordUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.InputStream;
import java.net.URL;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


@Slf4j
@Service
@Component("placementPositionInfoProvider")
public class PlacementPositionInfoProviderImpl extends BaseProviderImpl implements PlacementPositionInfoProvider {

    @Autowired
    private PlacementPositionInfoService placementPositionInfoService;

    @Autowired
    private GovOrgService govOrgService;

    @Autowired
    private PlacementInfoService placementInfoService;

    @Autowired
    private PlacementBatchService placementBatchService;

    @Autowired
    private PlacementUnitInfoService placementUnitInfoService;

    @Autowired
    private PlacementSoldierInfoService placementSoldierInfoService;

    @Autowired
    private PlacementSoldierAspirationResultService placementSoldierAspirationResultService;

    @Autowired
    private PlacementSoldierAspirationService placementSoldierAspirationService;

    @Autowired
    private GovEmployeeProvider govEmployeeProvider;

    @Autowired
    private PlacementThroughTrainApplyInfoService placementThroughTrainApplyInfoService;

    @Autowired
    private MiniCacheUtils miniCacheUtils;

    @Autowired
    private CommonDataDictService commonDataDictService;

    @Autowired
    private PlacementEventRecordService placementEventRecordService;

    @Autowired
    private PlacementSoldierInfoProvider placementSoldierInfoProvider;

    Pattern authPattern = Pattern.compile("jzaz_position_([0-9]{1})");


    @Override
    public BasePagingResponse<List<PlacementPositionInfoDTO>> searchPlacementPositionInfo(final PlacementPositionInfoSearchRequest searchRequest) {

        BizCheckUtil.checkNotNull(searchRequest, "查询分页PlacementPositionInfo的请求参数不能为空");
        BizCheckUtil.checkNotBlank(searchRequest.getEmployeeId(), "employeeId参数不能为空");


        String adminAreaCode = govOrgService.getAdminAreaCodeOfEmploy(searchRequest.getEmployeeId());
        PlacementInfoDO alivePlacement = null;
        if (Strings.isNotBlank(searchRequest.getYear())) {
            alivePlacement = placementInfoService.getByAdminCodeAndYear(adminAreaCode, searchRequest.getYear());
        }  else {
            alivePlacement = placementInfoService.getAlivePlacement(adminAreaCode);
        }
        if (alivePlacement == null) {
            return ResponseUtils.buildSuccessPagingResponse(new ArrayList<>());
        }

        final PlacementPositionInfoBSearcher placementPositionInfoBSearcher = PlacementPositionInfoProviderConverter.convertRequestSO2Searcher(searchRequest);
        if (Strings.isNotBlank(searchRequest.getType())) {
            PlacementBatchDO byPlacementIdAndType = placementBatchService.getByPlacementIdAndType(alivePlacement.getId(), searchRequest.getType());
            if (byPlacementIdAndType == null) {
                return ResponseUtils.buildSuccessPagingResponse(new ArrayList<>());
            }
            placementPositionInfoBSearcher.setBatchId(byPlacementIdAndType.getId());
        } else {
            List<PlacementBatchDO> placementBatchDOS = placementBatchService.listByPlacementId(alivePlacement.getId());
            List<String> batchIds = placementBatchDOS.stream().map(s -> s.getId()).collect(Collectors.toList());
            placementPositionInfoBSearcher.setBatchIds(batchIds);
        }

        final List<PlacementPositionInfoDO> placementPositionInfoDOList = placementPositionInfoService.search(placementPositionInfoBSearcher);
        final List<PlacementPositionInfoDTO> placementPositionInfoDTOList = PlacementPositionInfoProviderConverter.convertResponseDOList2DTOList(placementPositionInfoDOList);
        if (!CollectionUtils.isEmpty(placementPositionInfoDTOList)) {

            Boolean unifiedAuth = isUnifiedAuth(PlacementBatchTypeEnum.UNIFIED.name(), alivePlacement.getId());


            for (PlacementPositionInfoDTO placementPositionInfoDTO : placementPositionInfoDTOList) {
                placementPositionInfoDTO.setBatchType(miniCacheUtils.getCachedBatchType(placementPositionInfoDTO.getBatchId()));
                if (!PlacementBatchTypeEnum.UNIFIED.name().equals(placementPositionInfoDTO.getBatchType()) || unifiedAuth) {
                    placementPositionInfoDTO.setAdmissionsNum(placementSoldierAspirationResultService.countByPositionId(placementPositionInfoDTO.getId()));
                    placementPositionInfoDTO.setApplyNum(placementSoldierAspirationService.countByPositionId(placementPositionInfoDTO.getId(), ProcessStatusEnum.SUCCESS.name()));
                    placementPositionInfoDTO.setAllApplyNum(placementSoldierAspirationService.countByPositionId(placementPositionInfoDTO.getId(), null));
                }

            }
        }
        return ResponseUtils.buildSuccessPagingResponse(placementPositionInfoDTOList, placementPositionInfoBSearcher);
    }

    @Override
    public BasePagingResponse<List<PlacementPositionInfoDTO>> searchPlacementPositionInfoWithUnified(PlacementPositionInfoSearchRequest searchRequest) {

        BizCheckUtil.checkNotNull(searchRequest, "查询分页PlacementPositionInfo的请求参数不能为空");
        BizCheckUtil.checkNotBlank(searchRequest.getEmployeeId(), "employeeId参数不能为空");

        String adminAreaCode = govOrgService.getAdminAreaCodeOfEmploy(searchRequest.getEmployeeId());
        PlacementInfoDO alivePlacement = placementInfoService.getAlivePlacement(adminAreaCode);
        if (alivePlacement == null) {
            return ResponseUtils.buildSuccessPagingResponse(new ArrayList<>());
        }

        final PlacementPositionInfoBSearcher placementPositionInfoBSearcher = PlacementPositionInfoProviderConverter.convertRequestSO2Searcher(searchRequest);
        placementPositionInfoBSearcher.setPageNo(1);
        placementPositionInfoBSearcher.setPageSize(Integer.MAX_VALUE);
        final List<PlacementPositionInfoDO> placementPositionInfoDOList = placementPositionInfoService.search(placementPositionInfoBSearcher);

        List<PlacementPositionInfoDTO> placementPositionInfoDTOList = PlacementPositionInfoProviderConverter.convertResponseDOList2DTOList(placementPositionInfoDOList);
        Boolean unifiedAuth = isUnifiedAuth(searchRequest.getType(), alivePlacement.getId());
        if (!CollectionUtils.isEmpty(placementPositionInfoDTOList) && unifiedAuth) {

            PlacementBatchDO byPlacementIdAndType = placementBatchService.getByPlacementIdAndType(alivePlacement.getId(), PlacementBatchTypeEnum.UNIFIED.name());
            List<PlacementSoldierAspirationDO> aspirationDOS = placementSoldierAspirationService.listByBatchId(byPlacementIdAndType.getId());
            for (PlacementPositionInfoDTO positionInfoDTO : placementPositionInfoDTOList) {
                List<String> asps = extractAsp(aspirationDOS, positionInfoDTO.getId());
                Collections.sort(asps);
                positionInfoDTO.setAspList(String.join(",", asps));
            }
        }

        Collections.sort(placementPositionInfoDTOList, new Comparator<PlacementPositionInfoDTO>() {
            @Override
            public int compare(PlacementPositionInfoDTO o1, PlacementPositionInfoDTO o2) {
                if (Strings.isBlank(o1.getAspList()) && Strings.isBlank(o2.getAspList())) {
                    return 0;
                }
                if (Strings.isBlank(o1.getAspList())) {
                    return 1;
                }
                if (Strings.isBlank(o2.getAspList())) {
                    return -1;
                }
                return o1.getAspList().compareTo(o2.getAspList());
            }
        });

        placementPositionInfoDTOList = paging(searchRequest.getPageNo(), searchRequest.getPageSize(), placementPositionInfoDTOList);

        if (!CollectionUtils.isEmpty(placementPositionInfoDTOList)) {

            for (PlacementPositionInfoDTO placementPositionInfoDTO : placementPositionInfoDTOList) {
                placementPositionInfoDTO.setAspList(convertToAspCn(placementPositionInfoDTO.getAspList()));
                placementPositionInfoDTO.setBatchType(miniCacheUtils.getCachedBatchType(placementPositionInfoDTO.getBatchId()));
                if (unifiedAuth) {
                    placementPositionInfoDTO.setAdmissionsNum(placementSoldierAspirationResultService.countByPositionId(placementPositionInfoDTO.getId()));
                    placementPositionInfoDTO.setApplyNum(placementSoldierAspirationService.countByPositionId(placementPositionInfoDTO.getId(), ProcessStatusEnum.SUCCESS.name()));
                    placementPositionInfoDTO.setAllApplyNum(placementSoldierAspirationService.countByPositionId(placementPositionInfoDTO.getId(), null));
                }
            }
        }
        return ResponseUtils.buildSuccessPagingResponse(placementPositionInfoDTOList, placementPositionInfoBSearcher);
    }

    @Override
    public BasePagingResponse<List<PlacementPositionInfoDTO>> searchPlacementPositionInfoWithUnifiedOfAllAsp(PlacementPositionInfoSearchRequest searchRequest) {

        BizCheckUtil.checkNotNull(searchRequest, "查询分页PlacementPositionInfo的请求参数不能为空");
        BizCheckUtil.checkNotBlank(searchRequest.getEmployeeId(), "employeeId参数不能为空");

        String adminAreaCode = govOrgService.getAdminAreaCodeOfEmploy(searchRequest.getEmployeeId());
        PlacementInfoDO alivePlacement = placementInfoService.getAlivePlacement(adminAreaCode);
        if (alivePlacement == null) {
            return ResponseUtils.buildSuccessPagingResponse(new ArrayList<>());
        }
        Boolean aBoolean = placementSoldierInfoProvider.checkUniCanView(alivePlacement.getId());
        BizCheckUtil.checkIsTrue(aBoolean, "未到截止时间或先输入三重密码！");

        final PlacementPositionInfoBSearcher placementPositionInfoBSearcher = PlacementPositionInfoProviderConverter.convertRequestSO2Searcher(searchRequest);
        placementPositionInfoBSearcher.setPageNo(1);
        placementPositionInfoBSearcher.setPageSize(Integer.MAX_VALUE);
        final List<PlacementPositionInfoDO> placementPositionInfoDOList = placementPositionInfoService.search(placementPositionInfoBSearcher);

        PlacementBatchDO placementBatchDO = placementBatchService.getByPlacementIdAndType(alivePlacement.getId(), PlacementBatchTypeEnum.UNIFIED.name());

        Map<String, PlacementSoldierInfoDTO> soldierIdCardNoMap = calculateBatchMatchResultOfCtzy(placementBatchDO.getId());
        if (CollectionUtils.isEmpty(soldierIdCardNoMap)) {
            return ResponseUtils.buildSuccessPagingResponse(null);
        }


        List<PlacementPositionInfoDTO> result = new ArrayList<>();
        for (PlacementPositionInfoDO positionInfoDO : placementPositionInfoDOList) {
            final PlacementPositionInfoDTO positionInfoDTO = PlacementPositionInfoProviderConverter.convertResponseDO2DTO(positionInfoDO);
            result.add(positionInfoDTO);
        }

        return ResponseUtils.buildSuccessPagingResponse(result, placementPositionInfoBSearcher);
    }


    private String buildColour(PlacementSoldierInfoDTO soldierInfoDTO, PlacementSoldierAspirationDTO placementSoldierAspirationDTO) {
        if (Boolean.TRUE.equals(placementSoldierAspirationDTO.getRecruitFlag())) {
            return "#becfc6";

        }

        if (Boolean.TRUE.equals(placementSoldierAspirationDTO.getVirtualRecruit())) {
            return "#c2d4ff";

        }

        if (Boolean.TRUE.equals(soldierInfoDTO.getRecruitFlag()) && !Boolean.TRUE.equals(placementSoldierAspirationDTO.getRecruitFlag())) {
            return "#bef0e0";

        }

        return "#ffedb2";

    }

    private List<PlacementSoldierAspirationDTO> filterPositionAsp(List<PlacementSoldierAspirationDTO> aspirationDTOList, String id) {
        List<PlacementSoldierAspirationDTO> result = new ArrayList<>();
        for (PlacementSoldierAspirationDTO placementSoldierAspirationDTO : aspirationDTOList) {
            if (placementSoldierAspirationDTO.getPositionId().equals(id)) {
                result.add(placementSoldierAspirationDTO);
            }
        }
        return result;
    }

    private String convertToAspCn(String aspList) {
        if (Strings.isBlank(aspList)) {
            return null;
        }

        List<String> list = new ArrayList<>();
        String[] split = aspList.split(",");
        for (String s : split) {
            String s1 = intToCN(s);
            list.add("第" + s1 + "志愿");
        }
        return String.join(",", list);
    }

    private String intToCN(String i) {
        switch (i) {
            case "0":
                return "一";
            case "1":
                return "二";
            case "2":
                return "三";
            case "3":
                return "四";
            case "4":
                return "五";
            case "5":
                return "六";

        }
        return "";
    }

    public static <T> List<T> paging(Integer pageNo, Integer pageSize, List<T> list) {
        if (list == null) {
            list = new ArrayList<T>();
        }
        if (pageNo == null) {
            pageNo = 1;
        }
        if (pageSize == null) {
            pageSize = 10;
        }
        if (pageNo <= 0) {
            pageNo = 1;
        }

        int totalitems = list.size();
        List<T> pagingList = new ArrayList<T>();

        int totalNum = ((pageNo - 1) * pageSize) + pageSize > totalitems ? totalitems : ((pageNo - 1) * pageSize) + pageSize;
        for (int i = (pageNo - 1) * pageSize; i < totalNum; i++) {
            pagingList.add(list.get(i));
        }
        return pagingList;

    }

    private List<String> extractAsp(List<PlacementSoldierAspirationDO> aspirationDOS, String id) {
        Set<String> asps = new HashSet<>();
        for (PlacementSoldierAspirationDO aspirationDO : aspirationDOS) {
            if (aspirationDO.getPositionId().equals(id)) {
                asps.add(String.valueOf(aspirationDO.getSeqNo()));
            }
        }
        return Lists.newArrayList(asps);
    }


    private Boolean isUnifiedAuth(String type, String placementId) {
        Boolean isAuth = true;
        if (PlacementBatchTypeEnum.UNIFIED.name().equals(type)) {
            String year = DateUtil.format(new Date(), "yyyy");
            PlacementInfoDO placementInfoDO = placementInfoService.get(placementId);
            String prefix = placementInfoDO.getAdminAreaCode() + year;
            CommonDataDictDO pw1 = commonDataDictService.getByCode(prefix + "pw1");

            if (pw1 == null || !Boolean.TRUE.equals(pw1.getUsed())) {
                isAuth = false;
            }
        }
        return isAuth;
    }

    public static void main(String[] args) {
        List<String> s = Lists.newArrayList("", "2", "1", "1,2", "", "");
        Collections.sort(s, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                if (Strings.isBlank(o1)) {
                    return 1;
                }
                if (Strings.isBlank(o2)) {
                    return -1;
                }
                return o1.compareTo(o2);
            }
        });
        System.out.println(s);
    }

    @Override
    public BaseResponse<ExcelResultBO> exportPositionAspirationDetail(PlacementPositionInfoSearchRequest searchRequest) {

        searchRequest.setPageNo(1);
        searchRequest.setPageSize(Integer.MAX_VALUE);
        List<String> headers = Lists.newArrayList("单位", "岗位", "姓名", "身份证", "联系电话", "志愿", "档案分", "考试分", "综合分");
        List<List<String>> data = Lists.newArrayList();

        List<PlacementPositionInfoDTO> dto = searchPlacementPositionInfo(searchRequest).getDto();
        if (!CollectionUtils.isEmpty(dto)) {
            for (PlacementPositionInfoDTO positionInfoDTO : dto) {

                PlacementPositionInfoDTO newPositionDTO = new PlacementPositionInfoDTO();
                newPositionDTO.setRecruitList(Lists.newArrayList());
                newPositionDTO.setWaitList(Lists.newArrayList());
                PlacementPositionInfoDTO remoteObj = buildPositionAspView(positionInfoDTO.getId(), positionInfoDTO.getBatchId(), newPositionDTO);
                String unitName = positionInfoDTO.getUnitName();
                String name = positionInfoDTO.getName();
                List<PlacementSoldierInfoDTO> allList = Lists.newArrayList();
                allList.addAll(remoteObj.getRecruitList());
                allList.addAll(remoteObj.getWaitList());

                for (PlacementSoldierInfoDTO soldierInfoDTO : allList) {
                    List<String> item = Lists.newArrayList();
                    item.add(unitName);
                    item.add(name);
                    item.add(soldierInfoDTO.getRealName());
                    item.add(soldierInfoDTO.getIdCardNo());
                    item.add(soldierInfoDTO.getMobile());
                    item.add(String.valueOf(soldierInfoDTO.getSeqNo() + 1));
                    item.add(String.valueOf(soldierInfoDTO.getArchiveScore()));
                    item.add(String.valueOf(soldierInfoDTO.getExamScore()));
                    item.add(String.valueOf(soldierInfoDTO.getTotalScore()));
                    data.add(item);
                }
            }
        }

        return ResponseUtils.buildSuccessResponse(new ExcelResultBO("岗位详情", headers, data));
    }

    @Override
    public BasePagingResponse<List<PlacementPositionInfoDTO>> searchCheckList(PlacementPositionInfoSearchRequest searchRequest) {

        BizCheckUtil.checkNotNull(searchRequest, "查询分页PlacementPositionInfo的请求参数不能为空");
        BizCheckUtil.checkNotBlank(searchRequest.getEmployeeId(), "employeeId参数不能为空");
        BizCheckUtil.checkNotBlank(searchRequest.getAuditStatus(), "auditStatus不能为空");

        String adminAreaCode = govOrgService.getAdminAreaCodeOfEmploy(searchRequest.getEmployeeId());
        PlacementInfoDO alivePlacement = placementInfoService.getAlivePlacement(adminAreaCode);
        if (alivePlacement == null) {
            return ResponseUtils.buildSuccessPagingResponse(new ArrayList<>());
        }

        GovEmployeeDTO govEmployeeDTO = govEmployeeProvider.getRoles(searchRequest.getEmployeeId()).getDto();
        String level = getLevel(govEmployeeDTO.getResourceCodes());
        if (Strings.isBlank(level)) {
            return ResponseUtils.buildSuccessPagingResponse(null);
        }

        final PlacementPositionInfoBSearcher placementPositionInfoBSearcher = PlacementPositionInfoProviderConverter.convertRequestSO2Searcher(searchRequest);
        placementPositionInfoBSearcher.setAuditStatusList(buildStatus(searchRequest.getAuditStatus(), level));

        final List<PlacementPositionInfoDO> placementPositionInfoDOList = placementPositionInfoService.search(placementPositionInfoBSearcher);
        final List<PlacementPositionInfoDTO> placementPositionInfoDTOList = PlacementPositionInfoProviderConverter.convertResponseDOList2DTOList(placementPositionInfoDOList);
        if (!CollectionUtils.isEmpty(placementPositionInfoDTOList)) {

            for (PlacementPositionInfoDTO placementPositionInfoDTO : placementPositionInfoDTOList) {
                placementPositionInfoDTO.setBatchType(miniCacheUtils.getCachedBatchType(placementPositionInfoDTO.getBatchId()));
                placementPositionInfoDTO.setAdmissionsNum(placementSoldierAspirationResultService.countByPositionId(placementPositionInfoDTO.getId()));
                placementPositionInfoDTO.setApplyNum(placementSoldierAspirationService.countByPositionId(placementPositionInfoDTO.getId(), ProcessStatusEnum.SUCCESS.name()));
                placementPositionInfoDTO.setStatus(getCheckResult(placementPositionInfoDTO.getAuditStatus(), level));
            }
        }
        return ResponseUtils.buildSuccessPagingResponse(placementPositionInfoDTOList, placementPositionInfoBSearcher);
    }


    private String getCheckResult(String status, String level) {
        if (Strings.isBlank(status)) {
            return null;
        }
        Integer i = Integer.valueOf(level);

        if (status.contains(level + "_" + ProcessStatusEnum.REJECT.name())) {
            return ProcessStatusEnum.REJECT.name();
        }

        if (status.contains(level + "_" + ProcessStatusEnum.SUCCESS.name())) {
            return ProcessStatusEnum.SUCCESS.name();
        }

        for (int j = i + 1; j <= 4; j++) {
            if (status.contains(j + "_")) {
                return ProcessStatusEnum.SUCCESS.name();
            }
        }

        return ProcessStatusEnum.DEALING.name();
    }

    private List<String> buildStatus(String status, String level) {
        if (Strings.isBlank(status)) {
            return null;
        }

        List<String> statusList = Lists.newArrayList();
        if ("1".equals(level)) {
            if (status.equals(CheckStatusEnum.DEALING.name())) {
                statusList.add(CheckStatusEnum.DEALING.name());
            }
            if (status.equals(ProcessStatusEnum.SUCCESS.name())) {
                for (int i = 1; i <= 4; i++) {
                    statusList.add(i + "_" + ProcessStatusEnum.SUCCESS.name());
                    statusList.add(i + "_" + ProcessStatusEnum.REJECT.name());
                }

            }
        } else {
            Integer i = Integer.valueOf(level);
            if (status.equals(CheckStatusEnum.DEALING.name())) {
                statusList.add((i - 1) + "_" + ProcessStatusEnum.SUCCESS.name());
            }
            if (status.equals(ProcessStatusEnum.SUCCESS.name())) {
                for (int j = i; j <= 4; j++) {
                    statusList.add(j + "_" + ProcessStatusEnum.SUCCESS.name());
                    statusList.add(j + "_" + ProcessStatusEnum.REJECT.name());
                }

            }
        }
        return statusList;
    }

    @Override
    public BasePagingResponse<List<PlacementPositionInfoDTO>> searchSoldierPositions(PlacementPositionInfoSearchRequest searchRequest) {

        BizCheckUtil.checkNotNull(searchRequest, "查询分页PlacementPositionInfo的请求参数不能为空");
        BizCheckUtil.checkNotBlank(searchRequest.getSoldierId(), "soldierId不能为空");

        PlacementSoldierInfoDO bySoldierId = placementSoldierInfoService.getBySoldierId(searchRequest.getSoldierId());
        BizCheckUtil.checkNotNull(bySoldierId, "查无此人");
        PlacementBatchDO currentBatch = placementBatchService.getCurrentBatch(bySoldierId.getPlacementId());
        if (currentBatch == null) {
            return ResponseUtils.buildSuccessPagingResponse(new ArrayList<>());
        }





        PlacementPositionInfoBSearcher bSearcher = new PlacementPositionInfoBSearcher(searchRequest.getPageNo(), searchRequest.getPageSize());
        bSearcher.setBatchId(currentBatch.getId());
        bSearcher.setPublished(true);

        List<PlacementPositionInfoDO> search = placementPositionInfoService.search(bSearcher);
        List<PlacementPositionInfoDTO> placementPositionInfoDTOList = PlacementPositionInfoProviderConverter.convertResponseDOList2DTOList(search);

        return ResponseUtils.buildSuccessPagingResponse(placementPositionInfoDTOList, bSearcher);
    }

    private void checkHasThroughAuth(PlacementSoldierInfoDO bySoldierId, PlacementBatchDO currentBatch) {
        PlacementBatchTypeEnum byEnumName = PlacementBatchTypeEnum.getByEnumName(currentBatch.getType());
        BizCheckUtil.checkIsTrue(currentBatch.getId().equals(bySoldierId.getBatchId()), byEnumName.getDesc() + "批次-无权限");
        PlacementThroughTrainApplyInfoDO byIdCardNo = placementThroughTrainApplyInfoService.getByIdCardNo(bySoldierId.getIdCardNo());
        BizCheckUtil.checkIsTrue(byIdCardNo != null && ProcessStatusEnum.SUCCESS.name().equals(byIdCardNo.getStatus()), byEnumName.getDesc() + "批次-无权限");
    }

    private List<PlacementPositionInfoDTO> clearFullPosition(List<PlacementPositionInfoDTO> placementPositionInfoDTOList, List<PlacementSoldierAspirationResultDO> list) {
        if (CollectionUtils.isEmpty(placementPositionInfoDTOList)) {
            return placementPositionInfoDTOList;
        }
        for (PlacementPositionInfoDTO positionInfoDTO : placementPositionInfoDTOList) {
            if (positionInfoDTO.getUsed() == null) {
                positionInfoDTO.setUsed(0);
            }
        }
        if (CollectionUtils.isEmpty(list)) {
            return placementPositionInfoDTOList;
        }

        for (PlacementSoldierAspirationResultDO aspirationResultDO : list) {
            String positionId = aspirationResultDO.getPositionId();
            addUsed(placementPositionInfoDTOList, positionId);
        }

        placementPositionInfoDTOList.removeIf(next -> next.getUsed() != null && next.getUsed() >= next.getQuota());

        return placementPositionInfoDTOList;
    }

    private void addUsed(List<PlacementPositionInfoDTO> placementPositionInfoDTOList, String positionId) {
        for (PlacementPositionInfoDTO positionInfoDTO : placementPositionInfoDTOList) {
            if (positionInfoDTO.getId().equals(positionId)) {
                Integer used = positionInfoDTO.getUsed();
                if (used == null) {
                    positionInfoDTO.setUsed(1);
                } else {
                    positionInfoDTO.setUsed(used + 1);
                }
                return;
            }
        }
    }

    @Override
    public BaseResponse<PlacementPositionInfoDTO> getPlacementPositionInfo(final BaseGetRequest baseGetRequest) {

        BizCheckUtil.checkNotNull(baseGetRequest, "获取单条PlacementPositionInfo的请求参数不能为空");
        BizCheckUtil.checkNotBlank((String) baseGetRequest.getId(), "id不能为空");

        final PlacementPositionInfoDO placementPositionInfoDO = placementPositionInfoService.get((String) baseGetRequest.getId());
        final PlacementPositionInfoDTO remoteObj = PlacementPositionInfoProviderConverter.convertResponseDO2DTO(placementPositionInfoDO);
        remoteObj.setAdmissionsNum(placementSoldierAspirationResultService.countByPositionId(remoteObj.getId()));
        remoteObj.setApplyNum(placementSoldierAspirationService.countByPositionId(remoteObj.getId(), ProcessStatusEnum.SUCCESS.name()));
        remoteObj.setAllApplyNum(placementSoldierAspirationService.countByPositionId(remoteObj.getId(), null));

        remoteObj.setRecruitList(Lists.newArrayList());
        remoteObj.setWaitList(Lists.newArrayList());

        PlacementPositionInfoDTO resultObject = buildPositionAspView(placementPositionInfoDO.getId(), placementPositionInfoDO.getBatchId(), remoteObj);
        return ResponseUtils.buildSuccessResponse(resultObject);
    }

    @Override
    public BaseResponse<PlacementPositionInfoDTO> getByCode(String code) {

        if (Strings.isBlank(code)) {
            return ResponseUtils.buildSuccessResponse(null);
        }

        final PlacementPositionInfoDO placementPositionInfoDO = placementPositionInfoService.getByCode(code);
        final PlacementPositionInfoDTO remoteObj = PlacementPositionInfoProviderConverter.convertResponseDO2DTO(placementPositionInfoDO);

        return ResponseUtils.buildSuccessResponse(remoteObj);
    }

    private PlacementPositionInfoDTO buildPositionAspView(String positionId, String batchId, PlacementPositionInfoDTO remoteObj) {
        PlacementBatchDO placementBatchDO = placementBatchService.get(batchId);


        if (PlacementBatchTypeEnum.THROUGH_TRAIN.name().equals(placementBatchDO.getType())) {
            List<PlacementSoldierInfoDO> allSoldiers = placementSoldierInfoService.listShortInfoByPlacement(placementBatchDO.getPlacementId());

            List<PlacementSoldierAspirationDO> aspirations = placementSoldierAspirationService.getByPositionId(positionId, ThroughTrainProcessEnum.SUCCESS.name());

            List<PlacementSoldierInfoDTO> notAdmittedAndToThisSoldiers = Lists.newArrayList();


            for (PlacementSoldierAspirationDO aspiration : aspirations) {
                PlacementSoldierInfoDO soldierInfoDO = placementSoldierInfoService.getByIdCardNo(aspiration.getIdCardNo());
                final PlacementSoldierInfoDTO soldierInfoDTO = PlacementSoldierInfoProviderConverter.convertResponseDO2DTO(soldierInfoDO);
                PlacementSoldierAspirationResultDO resultDO = placementSoldierAspirationResultService.getByIdCardNo(soldierInfoDTO.getIdCardNo());

                soldierInfoDTO.setRecruitFlag(false);
                soldierInfoDTO.setRank(getRank(soldierInfoDTO, allSoldiers));
                soldierInfoDTO.setSeqNo(aspiration.getSeqNo());
                soldierInfoDTO.setAspId(aspiration.getId());
                soldierInfoDTO.setConfirmAttachment(aspiration.getConfirmAttachment());
                soldierInfoDTO.setConfirmRemark(aspiration.getConfirmRemark());
                soldierInfoDTO.setAttachment(aspiration.getAttachment());
                soldierInfoDTO.setRemark(aspiration.getRemark());
                soldierInfoDTO.setSign(aspiration.getSign());
                if (resultDO != null) {
                    if (!resultDO.getPositionId().equals(positionId)) {
                        soldierInfoDTO.setRecruitFlag(true);
                        notAdmittedAndToThisSoldiers.add(soldierInfoDTO);
                    } else {
                        soldierInfoDTO.setRecruitFlag(true);
                        notAdmittedAndToThisSoldiers.add(soldierInfoDTO);
                    }
                } else {
                    soldierInfoDTO.setRecruitFlag(false);
                    notAdmittedAndToThisSoldiers.add(soldierInfoDTO);
                }
            }

            if (PlacementBatchTypeEnum.THROUGH_TRAIN.name().equals(remoteObj.getType()) &&
                    ThroughTrainTypeEnum.SGAJ.name().equals(remoteObj.getThroughTrainType())) {
                sortSoldierByArchiveScore(notAdmittedAndToThisSoldiers);
            } else {

                sortSoldierByName(notAdmittedAndToThisSoldiers);
            }

            for (PlacementSoldierInfoDTO soldierInfoDTO : notAdmittedAndToThisSoldiers) {
                fillThoughTrain(soldierInfoDTO, remoteObj);
            }

            return remoteObj;

        } else {
            List<PlacementSoldierInfoDTO> waitList = Lists.newArrayList();
            List<PlacementSoldierInfoDTO> recruitList = Lists.newArrayList();

            Map<String, PlacementSoldierInfoDTO> soldierIdCardNoMap = calculateBatchMatchResultOfCtzy(placementBatchDO.getId());
            List<PlacementSoldierAspirationDO> aspirations = placementSoldierAspirationService.getByPositionId(positionId, ThroughTrainProcessEnum.SUCCESS.name());

            for (PlacementSoldierAspirationDO aspiration : aspirations) {
                final PlacementSoldierInfoDTO soldierInfoDTO = soldierIdCardNoMap.get(aspiration.getIdCardNo());
                soldierInfoDTO.setSign(aspiration.getSign());
                soldierInfoDTO.setSeqNo(aspiration.getSeqNo());
                soldierInfoDTO.setAspId(aspiration.getId());

                PlacementSoldierAspirationDTO asInSoldier = getTarget(soldierInfoDTO.getAspiration(), aspiration.getId());
                if (PlacementAspirationResultStatusEnum.SUCCESS.name().equals(asInSoldier.getAdmitted())) {
                    recruitList.add(soldierInfoDTO);
                } else {
                    waitList.add(soldierInfoDTO);
                }
            }


            sortSoldier(recruitList);
            sortSoldier(waitList);

            remoteObj.setRecruitList(recruitList);
            remoteObj.setWaitList(waitList);
            return remoteObj;
        }
    }

    private void sortSoldier(List<PlacementSoldierInfoDTO> admittedSoldiers) {
        Collections.sort(admittedSoldiers, new Comparator<PlacementSoldierInfoDTO>() {
            @Override
            public int compare(PlacementSoldierInfoDTO o1, PlacementSoldierInfoDTO o2) {
                int seqC = o2.getSeqNo().compareTo(o1.getSeqNo());
                if (seqC != 0) {
                    return -seqC;
                }
                if (o1.getTotalScore() == null || o2.getTotalScore() == null) {
                    return -1;
                }

                int i = o2.getTotalScore().compareTo(o1.getTotalScore());
                if (i == 0) {
                    return o2.getArchiveScore().compareTo(o1.getArchiveScore());
                }
                return i;
            }
        });
    }

    private void sortSoldierByArchiveScore(List<PlacementSoldierInfoDTO> admittedSoldiers) {
        admittedSoldiers.sort(new Comparator<PlacementSoldierInfoDTO>() {
            @Override
            public int compare(PlacementSoldierInfoDTO o1, PlacementSoldierInfoDTO o2) {
                if (o1.getArchiveScore() == null || o2.getArchiveScore() == null) {
                    return -1;
                }
                return o2.getArchiveScore().compareTo(o1.getArchiveScore());
            }
        });
    }

    private void sortSoldierByName(List<PlacementSoldierInfoDTO> admittedSoldiers) {
        admittedSoldiers.sort(new Comparator<PlacementSoldierInfoDTO>() {
            @Override
            public int compare(PlacementSoldierInfoDTO o1, PlacementSoldierInfoDTO o2) {
                return o1.getRealName().compareTo(o2.getRealName());
            }
        });
    }

    private PlacementSoldierAspirationDTO getTarget(List<PlacementSoldierAspirationDTO> aspiration, String id) {
        for (PlacementSoldierAspirationDTO placementSoldierAspirationDTO : aspiration) {
            if (placementSoldierAspirationDTO.getId().equals(id)) {
                return placementSoldierAspirationDTO;
            }
        }
        return null;
    }



    public Map<String, PlacementSoldierInfoDTO> calculateBatchMatchResultOfCtzy(String batchId) {

        BizCheckUtil.checkNotNull(batchId, "请求不能为空");

        PlacementBatchDO placementBatchDO = placementBatchService.get(batchId);
        BizCheckUtil.checkNotNull(placementBatchDO, "批次不存在");

        List<PlacementPositionInfoDO> placementPositionInfoDOS = placementPositionInfoService.listByBatchId(batchId);
        final List<PlacementPositionInfoDTO> positionDTOS = PlacementPositionInfoProviderConverter.convertResponseDOList2DTOList(placementPositionInfoDOS);
        Map<String, PlacementPositionInfoDTO> positionMap = positionDTOS.stream().map(s -> {
            s.setUsed(0);
            s.setWaited(0);
            s.setRecruitList(Lists.newArrayList());
            return s;
        }).collect(Collectors.toMap(PlacementPositionInfoDTO::getId, s -> s));


        List<PlacementSoldierInfoDO> placementSoldierInfoDOS = placementSoldierInfoService.listSoldierByPositionBatch(batchId);
        final List<PlacementSoldierInfoDTO> soldierInfoDTOS = PlacementSoldierInfoProviderConverter.convertResponseDOList2DTOList(placementSoldierInfoDOS);
        for (PlacementSoldierInfoDTO soldier : soldierInfoDTOS) {
            if (soldier.getExamScore() == null || soldier.getTotalScore() == null) {
                throw new BizException(ErrorCodeEnum.ILLEGAL_PARAM, "考试分未导入");
            }
        }

        if (CollectionUtils.isEmpty(soldierInfoDTOS) || CollectionUtils.isEmpty(positionDTOS)) {
            return null;
        }
        Map<String, PlacementSoldierInfoDTO> soldierIdCardNoMap = soldierInfoDTOS.stream().collect(Collectors.toMap(PlacementSoldierInfoDTO::getIdCardNo, s -> s));

        PlacementSoldierInfoProviderConverter.sortListByScore(soldierInfoDTOS);


        List<PlacementSoldierAspirationDO> aspirationDOS = placementSoldierAspirationService.listByBatchId(batchId);
        List<PlacementSoldierAspirationDTO> aspirationDTOS = PlacementSoldierAspirationProviderConverter.convertResponseDOList2DTOList(aspirationDOS);
        List<PlacementSoldierAspirationResultDO> placementSoldierAspirationResultDOS = placementSoldierAspirationResultService.listByBatchId(batchId);
        List<PlacementSoldierAspirationResultDTO> aspirationResultDTOS = PlacementSoldierAspirationResultProviderConverter.convertResponseDOList2DTOList(placementSoldierAspirationResultDOS);

        for (PlacementSoldierAspirationResultDTO aspirationResultDTO : aspirationResultDTOS) {
            PlacementSoldierAspirationDTO aspiration = getAspirationByIdCardNoAndPosition(aspirationDTOS, aspirationResultDTO.getIdCardNo(), aspirationResultDTO.getPositionId());
            if (aspiration != null) {
                aspiration.setAdmitted(PlacementAspirationResultStatusEnum.SUCCESS.name());
                PlacementPositionInfoDTO positionInfoDTO = positionMap.get(aspiration.getPositionId());
                positionInfoDTO.setUsed(positionInfoDTO.getUsed() + 1);
                PlacementSoldierInfoDTO soldierInfoDTO = soldierIdCardNoMap.get(aspiration.getIdCardNo());
                if (soldierInfoDTO == null) {
                    continue;
                }
                soldierInfoDTO.setRecruitFlag(true);
                soldierInfoDTO.setVirtualRecruit(true);
                aspiration.setRecruitFlag(true);
                aspiration.setVirtualRecruit(true);
            }
        }



        for (PlacementSoldierInfoDTO soldierInfoDTO : soldierInfoDTOS) {
            List<PlacementSoldierAspirationDTO> aspirationDOList = aspirationDTOS.stream().filter(s -> s.getIdCardNo().equals(soldierInfoDTO.getIdCardNo())).sorted(new Comparator<PlacementSoldierAspirationDTO>() {
                @Override
                public int compare(PlacementSoldierAspirationDTO o1, PlacementSoldierAspirationDTO o2) {
                    return o1.getSeqNo().compareTo(o2.getSeqNo());
                }
            }).collect(Collectors.toList());
            soldierInfoDTO.setAspiration(aspirationDOList);
        }

        for (int i = 1; i <= 6; i++) {
            for (int s = 0; s < soldierInfoDTOS.size(); s++) {
                PlacementSoldierInfoDTO soldierInfoDTO = soldierInfoDTOS.get(s);
                if (Boolean.TRUE.equals(soldierInfoDTO.getVirtualRecruit())) {
                    continue;
                }

                List<PlacementSoldierAspirationDTO> aspiration = soldierInfoDTO.getAspiration();
                if (!CollectionUtils.isEmpty(aspiration)) {
                    if (aspiration.size() >= i) {
                        PlacementSoldierAspirationDTO placementSoldierAspirationDTO = aspiration.get(i - 1);
                        if (Strings.isBlank(placementSoldierAspirationDTO.getAdmitted())) {

                            PlacementPositionInfoDTO positionInfoDTO = positionMap.get(placementSoldierAspirationDTO.getPositionId());
                            if (positionInfoDTO == null) {
                                continue;
                            }
                            if (positionInfoDTO.getUsed() < positionInfoDTO.getQuota()) {
                                placementSoldierAspirationDTO.setAdmitted(PlacementAspirationResultStatusEnum.SUCCESS.name());
                                placementSoldierAspirationDTO.setVirtualRecruit(true);
                                positionInfoDTO.setUsed(positionInfoDTO.getUsed() + 1);
                                soldierInfoDTO.setVirtualRecruit(true);
                            } else {
                                placementSoldierAspirationDTO.setAdmitted(PlacementAspirationResultStatusEnum.FAILED.name());


                                if (s > 0) {
                                    PlacementSoldierInfoDTO previousSoldier = soldierInfoDTOS.get(s - 1);
                                    if (previousSoldier.getAspiration().size() >= i) {
                                        PlacementSoldierAspirationDTO previousOneAsp = previousSoldier.getAspiration().get(i - 1);
                                        if (soldierInfoDTO.getTotalScore().equals(previousSoldier.getTotalScore())
                                                && soldierInfoDTO.getArchiveScore().equals(previousSoldier.getArchiveScore())
                                                && previousOneAsp.getId().equals(placementSoldierAspirationDTO.getId())) {
                                            throw new BizException(ErrorCodeEnum.ILLEGAL_PARAM, previousSoldier.getRealName()
                                                    + "与" + soldierInfoDTO.getRealName() + "存在总分档案分和志愿重复的情况。志愿："
                                                    + previousOneAsp.getUnitName() + previousOneAsp.getPositionName());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        return soldierIdCardNoMap;
    }

    private PlacementSoldierAspirationDTO getAspirationByIdCardNoAndPosition(List<PlacementSoldierAspirationDTO> aspirationDTOS, String idCardNo, String positionId) {
        for (PlacementSoldierAspirationDTO aspirationDTO : aspirationDTOS) {
            if (aspirationDTO.getIdCardNo().equals(idCardNo) && aspirationDTO.getPositionId().equals(positionId)) {
                return aspirationDTO;
            }
        }
        return null;
    }

    @Transactional
    @Override
    public BaseResponse<Integer> checkPosition(PlacementPositionInfoUpdateRequest request) {


        BizCheckUtil.checkNotNull(request, "请求不能为空");
        BizCheckUtil.checkNotBlank(request.getId(), "id不能为空");
        BizCheckUtil.checkNotBlank(request.getEmployeeId(), "employeeId不能为空");
        BizCheckUtil.checkNotBlank(request.getStatus(), "状态不能为空");
        ProcessStatusEnum byEnumName = ProcessStatusEnum.getByEnumName(request.getStatus());
        BizCheckUtil.checkIsTrue(byEnumName != null && (byEnumName.equals(ProcessStatusEnum.SUCCESS) || byEnumName.equals(ProcessStatusEnum.REJECT)), "状态错误");

        GovEmployeeDTO govEmployeeDTO = govEmployeeProvider.getRoles(request.getEmployeeId()).getDto();
        String level = getLevel(govEmployeeDTO.getResourceCodes());
        BizCheckUtil.checkNotBlank(level, "暂无权限");

        String adminAreaCode = govOrgService.getAdminAreaCodeOfEmploy(request.getEmployeeId());
        PlacementInfoDO alivePlacement = placementInfoService.getAlivePlacement(adminAreaCode);

        List<PlacementPositionInfoDO> thisPositions = Lists.newArrayList();
        Set<String> batchIdSet = Sets.newHashSet();
        String[] idList = request.getId().split(",");
        for (String item : idList) {
            PlacementPositionInfoDO positionInfoDO = placementPositionInfoService.get(item);
            thisPositions.add(positionInfoDO);

            positionInfoDO.setAuditStatus(TwoLevelCheckUtils.buildCheckStatus(positionInfoDO.getAuditStatus(), level, byEnumName.name()));
            placementPositionInfoService.update(positionInfoDO);

            batchIdSet.add(positionInfoDO.getBatchId());
        }

        if (ProcessStatusEnum.SUCCESS.name().equals(byEnumName.name())) {
            for (String batchId : batchIdSet) {
                PlacementBatchDO placementBatchDO = placementBatchService.get(batchId);

                if (PlacementBatchTypeEnum.THROUGH_TRAIN.name().equals(placementBatchDO.getType())) {
                    sendAspResult(thisPositions);
                }


                List<PlacementPositionInfoDO> placementPositionInfoDOS = placementPositionInfoService.listByBatchId(batchId);
                if (checkIsAllPassed(placementPositionInfoDOS)) {






                    if (!PlacementBatchTypeEnum.THROUGH_TRAIN.name().equals(placementBatchDO.getType())) {
                        sendAspResult(placementBatchDO);
                    }










                }
            }
        } else {
            for (String batchId : batchIdSet) {
                PlacementBatchDO placementBatchDO = placementBatchService.get(batchId);


                if (PlacementBatchTypeEnum.THROUGH_TRAIN.name().equals(placementBatchDO.getType())) {
                    for (String item : idList) {
                        PlacementPositionInfoDO positionInfoDO = placementPositionInfoService.get(item);
                        positionInfoDO.setStatus(ProcessStatusEnum.DEALING.name());
                        RequestSetUtils.setModifierInfo(placementBatchDO, request);
                        placementBatchService.update(placementBatchDO);


                        placementSoldierAspirationResultService.deleteByPositionId(positionInfoDO.getId(), request.getModifierType(), request.getModifierId());
                    }
                } else {

                    PlacementBatchDO unifiedBatch = placementBatchService.getByPlacementIdAndType(alivePlacement.getId(), PlacementBatchTypeEnum.UNIFIED.name());
                    List<PlacementPositionInfoDO> placementPositionInfoDOS = placementPositionInfoService.listByBatchId(unifiedBatch.getId());
                    for (PlacementPositionInfoDO positionInfoDO : placementPositionInfoDOS) {
                        positionInfoDO.setStatus(ProcessStatusEnum.DEALING.name());
                        RequestSetUtils.setModifierInfo(placementBatchDO, request);
                        placementBatchService.update(placementBatchDO);


                        placementSoldierAspirationResultService.deleteByPositionId(positionInfoDO.getId(), request.getModifierType(), request.getModifierId());
                    }


                    PlacementBatchDO offlineBatch = placementBatchService.getByPlacementIdAndType(alivePlacement.getId(), PlacementBatchTypeEnum.OFFLINE.name());
                    List<PlacementPositionInfoDO> offlinePositions = placementPositionInfoService.listByBatchId(unifiedBatch.getId());
                    for (PlacementPositionInfoDO positionInfoDO : offlinePositions) {
                        positionInfoDO.setStatus(ProcessStatusEnum.DEALING.name());
                        RequestSetUtils.setModifierInfo(placementBatchDO, request);
                        placementBatchService.update(placementBatchDO);


                        placementSoldierAspirationResultService.deleteByPositionId(positionInfoDO.getId(), request.getModifierType(), request.getModifierId());
                    }
                }
            }
        }

        return ResponseUtils.buildSuccessResponse(0);
    }

    @Transactional
    @Override
    public BaseResponse<Integer> toNextBatch(PlacementPositionInfoUpdateRequest request) {

        BizCheckUtil.checkNotNull(request, "请求不能为空");
        BizCheckUtil.checkNotBlank(request.getEmployeeId(), "employeeId不能为空");
        String adminAreaCode = govOrgService.getAdminAreaCodeOfEmploy(request.getEmployeeId());
        PlacementInfoDO alivePlacement = placementInfoService.getAlivePlacement(adminAreaCode);
        PlacementBatchDO placementBatchDO = placementBatchService.getCurrentBatch(alivePlacement.getId());
        BizCheckUtil.checkNotNull(placementBatchDO, "无批次！");

        List<PlacementPositionInfoDO> placementPositionInfoDOS = placementPositionInfoService.listByBatchId(placementBatchDO.getId());
        for (PlacementPositionInfoDO placementPositionInfoDO : placementPositionInfoDOS) {
            BizCheckUtil.checkIsTrue("3_SUCCESS".equals(placementPositionInfoDO.getAuditStatus()), "当前批次存在没有审批完的岗位！("
                    + placementPositionInfoDO.getUnitName() + placementPositionInfoDO.getName() + ")");
        }

        placementBatchDO.setStatus(ProcessStatusEnum.SUCCESS.name());
        placementBatchDO.setAuditStatus(ProcessStatusEnum.SUCCESS.name());
        RequestSetUtils.setModifierInfo(placementBatchDO, request);
        placementBatchService.update(placementBatchDO);


        if (PlacementBatchTypeEnum.THROUGH_TRAIN.name().equals(placementBatchDO.getType())) {
            List<PlacementPositionInfoDTO> lastPosition = listPositionByBatchId(placementBatchDO.getId());

            for (PlacementPositionInfoDTO positionInfoDTO : lastPosition) {
                PlacementBatchDO currentBatch = placementBatchService.getCurrentBatch(placementBatchDO.getPlacementId());
                insertRemainingPosition(positionInfoDTO, currentBatch.getId(), request);
            }
        }

        placementSoldierAspirationService.updateCheckFlag(placementBatchDO.getPlacementId(), "Y");

        return ResponseUtils.buildSuccessResponse(0);
    }

    private void sendAspResult(PlacementBatchDO placementBatchDO) {
        List<PlacementSoldierAspirationDO> aspirationDOS = placementSoldierAspirationService.listByBatchId(placementBatchDO.getId(), ThroughTrainProcessEnum.SUCCESS.name());
        Set<String> idCardSet = aspirationDOS.stream().map(s -> s.getIdCardNo()).collect(Collectors.toSet());
        sendResultMsg(placementBatchDO, idCardSet);
    }

    private void sendAspResult(List<PlacementPositionInfoDO> positionInfoDOS) {
        for (PlacementPositionInfoDO positionInfoDO : positionInfoDOS) {
            if (!"3_SUCCESS".equals(positionInfoDO.getAuditStatus())) {
                continue;
            }
            PlacementBatchDO placementBatchDO = placementBatchService.get(positionInfoDO.getBatchId());
            List<PlacementSoldierAspirationDO> aspirationDOS = placementSoldierAspirationService.getByPositionId(positionInfoDO.getId(), ThroughTrainProcessEnum.SUCCESS.name());
            Set<String> idCardSet = aspirationDOS.stream().map(s -> s.getIdCardNo()).collect(Collectors.toSet());


            positionInfoDO.setPublished(false);
            positionInfoDO.setFinished(true);
            placementPositionInfoService.update(positionInfoDO);
            sendResultMsg(placementBatchDO, idCardSet);
        }
    }

    private void sendResultMsg(PlacementBatchDO placementBatchDO, Set<String> idCardSet) {
        for (String idCardNo : idCardSet) {
            PlacementSoldierAspirationResultDO aspirationResultDO = placementSoldierAspirationResultService.getByIdCardNo(idCardNo);
            String msg = null;
            if (aspirationResultDO != null) {
                String cachedPlacementPositionName = miniCacheUtils.getCachedPlacementPositionName(aspirationResultDO.getPositionId());
                msg = PlacementBatchTypeEnum.getByEnumName(placementBatchDO.getType()).getDesc() + ":成功:" + cachedPlacementPositionName;
            } else {
                msg = PlacementBatchTypeEnum.getByEnumName(placementBatchDO.getType()).getDesc() + ":不成功";
            }
            placementEventRecordService.insertEventRecord(idCardNo, msg);
        }
    }

    private boolean checkIsAllPassed(List<PlacementPositionInfoDO> placementPositionInfoDOS) {
        for (PlacementPositionInfoDO placementPositionInfoDO : placementPositionInfoDOS) {
            if (placementPositionInfoDO.getAuditStatus() == null || !placementPositionInfoDO.getAuditStatus().contains("3_SUCCESS")) {
                return false;
            }
        }
        return true;
    }


    private boolean fillThoughTrain(PlacementSoldierInfoDTO soldierInfoDTO, PlacementPositionInfoDTO remoteObj) {
        Integer quota = remoteObj.getQuota();

        if (PlacementBatchTypeEnum.THROUGH_TRAIN.name().equals(remoteObj.getType()) &&
                ThroughTrainTypeEnum.SGAJ.name().equals(remoteObj.getThroughTrainType())) {

            double v = quota * 0.1;
            int girlQuota = (int) v;
            if (v % 1 >= 0.5) {
                girlQuota++;
            }

            if (soldierInfoDTO.getGender().equals(GenderEnum.FEMALE.name())) {
                int girlNum = 0;
                for (PlacementSoldierInfoDTO placementSoldierInfoDTO : remoteObj.getRecruitList()) {
                    if (placementSoldierInfoDTO.getGender().equals(GenderEnum.FEMALE.name())) {
                        girlNum++;
                    }
                }

                if (girlQuota > girlNum) {
                    remoteObj.getRecruitList().add(soldierInfoDTO);
                    return true;
                } else {
                    remoteObj.getWaitList().add(soldierInfoDTO);
                }
            } else {
                remoteObj.getRecruitList().add(soldierInfoDTO);
            }
        } else {
            remoteObj.getRecruitList().add(soldierInfoDTO);
        }
        return true;
    }

    private boolean fillList(PlacementSoldierInfoDTO soldierInfoDTO, PlacementPositionInfoDTO remoteObj) {
        Integer quota = remoteObj.getQuota();

        if (!checkIsFull(remoteObj.getRecruitList(), quota)) {
            if (PlacementBatchTypeEnum.THROUGH_TRAIN.name().equals(remoteObj.getType()) &&
                    ThroughTrainTypeEnum.SGAJ.name().equals(remoteObj.getThroughTrainType())) {

                double v = quota * 0.1;
                int girlQuota = (int) v;
                if (v % 1 >= 0.5) {
                    girlQuota++;
                }

                if (soldierInfoDTO.getGender().equals(GenderEnum.FEMALE.name())) {
                    int girlNum = 0;
                    for (PlacementSoldierInfoDTO placementSoldierInfoDTO : remoteObj.getRecruitList()) {
                        if (placementSoldierInfoDTO.getGender().equals(GenderEnum.FEMALE.name())) {
                            girlNum++;
                        }
                    }

                    if (girlQuota > girlNum) {
                        remoteObj.getRecruitList().add(soldierInfoDTO);
                        return true;
                    } else {
                        remoteObj.getWaitList().add(soldierInfoDTO);
                    }
                } else {
                    remoteObj.getRecruitList().add(soldierInfoDTO);
                }
            } else {
                remoteObj.getRecruitList().add(soldierInfoDTO);
            }
        } else if (CollectionUtils.isEmpty(remoteObj.getWaitList())) {

            PlacementSoldierInfoDTO lastSoldier = remoteObj.getRecruitList().get(remoteObj.getRecruitList().size() - 1);
            if (PlacementBatchTypeEnum.THROUGH_TRAIN.name().equals(remoteObj.getType())) {
                if (lastSoldier.getArchiveScore().equals(soldierInfoDTO.getArchiveScore())) {
                    remoteObj.getRecruitList().add(soldierInfoDTO);
                } else {
                    remoteObj.getWaitList().add(soldierInfoDTO);
                }
            } else if (PlacementBatchTypeEnum.UNIFIED.name().equals(remoteObj.getType())) {
                if (lastSoldier.getArchiveScore().equals(soldierInfoDTO.getArchiveScore())
                        && lastSoldier.getTotalScore() != null
                        && lastSoldier.getTotalScore().equals(soldierInfoDTO.getTotalScore())) {
                    remoteObj.getRecruitList().add(soldierInfoDTO);
                } else {
                    remoteObj.getWaitList().add(soldierInfoDTO);
                }
            }
        } else {
            remoteObj.getWaitList().add(soldierInfoDTO);
        }
        return true;
    }

    private boolean checkIsFull(List<PlacementSoldierInfoDTO> recruitList, Integer quota) {
        if (recruitList.size() < quota) {
            return false;
        }
        return true;
    }

    private Integer getRank(PlacementSoldierInfoDTO soldierInfo, List<PlacementSoldierInfoDO> allSoldiers) {
        Double totalScore = soldierInfo.getTotalScore();
        if (totalScore == null) {
            return null;
        }
        int rank = 1;
        for (PlacementSoldierInfoDO soldier : allSoldiers) {
            if (soldier.getTotalScore() != null) {
                if (totalScore < soldier.getTotalScore()) {
                    rank++;
                }
            }
        }

        return rank;
    }


    @Override
    public BaseResponse<String> insertPlacementPositionInfo(final PlacementPositionInfoInsertRequest insertRequest) {

        final BaseResponse<String> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(insertRequest, "新增PlacementPositionInfo的请求参数不能为空");
            }

            @Override
            public void executeService() {
                final PlacementPositionInfoDO placementPositionInfoDO = PlacementPositionInfoProviderConverter.convertRequestIO2DO(insertRequest);
                placementPositionInfoService.insert(placementPositionInfoDO);
                ResponseUtils.setupSuccessResponse(baseResponse, placementPositionInfoDO.getId());
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.PLACEMENT_POSITION_INFO_INSERT;
            }
        });
        return baseResponse;
    }

    @Transactional
    @Override
    public BaseResponse<String> importPlacementPositions(SimpleApiRequest request) {

        BizCheckUtil.checkNotNull(request, "请求不能为空");
        BizCheckUtil.checkNotNull(request.getUrl(), "文件不能为空");
        BizCheckUtil.checkNotNull(request.getEmployeeId(), "employeeId不能为空");

        String adminAreaCode = govOrgService.getAdminAreaCodeOfEmploy(request.getEmployeeId());
        PlacementInfoDO alivePlacement = placementInfoService.getAlivePlacement(adminAreaCode);
        BizCheckUtil.checkNotNull(alivePlacement, "暂无安置");
        PlacementBatchDO byPlacementIdAndType = placementBatchService.getByPlacementIdAndType(alivePlacement.getId(), PlacementBatchTypeEnum.UNIFIED.name());
        BizCheckUtil.checkNotNull(byPlacementIdAndType, "暂无批次");

        String url = request.getUrl();
        url = url.replace("115.227.32.11", "172.18.102.62");
        try {
            URL source = new URL(url);
            InputStream inputStream = source.openStream();
            ExcelReader reader = ExcelUtil.getReader(inputStream);

            final List<List<Object>> read = reader.read();


            List<Object> objects = read.get(0);
            checkSoldierImportTemplate(objects, "编号", "单位", "岗位名称", "数量");
            for (int i = 1; i < read.size(); i++) {
                List<Object> item = read.get(i);
                String code = (String) item.get(0);
                String unitName = (String) item.get(1);
                String name = (String) item.get(2);
                Object quota = item.get(3);

                PlacementUnitInfoDO orInsertUnit = placementUnitInfoService.getOrInsertUnit(unitName);
                PlacementPositionInfoDO positionInfoDO = new PlacementPositionInfoDO();
                positionInfoDO.setBatchId(byPlacementIdAndType.getId());
                positionInfoDO.setUnitId(orInsertUnit.getId());
                positionInfoDO.setCode(code);
                positionInfoDO.setUnitName(orInsertUnit.getName());
                positionInfoDO.setName(name);
                positionInfoDO.setType(byPlacementIdAndType.getType());
                positionInfoDO.setQuota(convertToInt(quota));
                positionInfoDO.setPublished(false);
                positionInfoDO.setStatus(ProcessStatusEnum.DEALING.name());
                placementPositionInfoService.insert(positionInfoDO);
            }

        } catch (Exception e) {
            log.error("导入出错：{}", e);
            throw new BizException(ErrorCodeEnum.ILLEGAL_PARAM);
        }
        return ResponseUtils.buildSuccessResponse("0");
    }

    private Integer convertToInt(Object quota) {
        return Integer.valueOf(quota.toString());
    }

    private void checkSoldierImportTemplate(List<Object> headers, String... names) {
        for (int i = 0; i < names.length; i++) {
            BizCheckUtil.checkIsTrue(((String) headers.get(i)).startsWith(names[i]), "模板错误");
        }
    }


    @Override
    public BaseResponse<Integer> updatePlacementPositionInfo(final PlacementPositionInfoUpdateRequest updateRequest) {

        final BaseResponse<Integer> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(updateRequest, "修改PlacementPositionInfo的请求参数不能为空");
                BizCheckUtil.checkNotBlank(updateRequest.getId(), "id不能为空");
                BizCheckUtil.checkNotBlank(updateRequest.getModifierId(), "操作人不能为空");
                BizCheckUtil.checkNotBlank(updateRequest.getModifierType(), "操作人类型不能为空");
            }

            @Override
            public void executeService() {
                PlacementPositionInfoDO placementPositionInfoDO = PlacementPositionInfoProviderConverter.convertRequestUO2DO(updateRequest);
                Integer affectRowNum = placementPositionInfoService.update(placementPositionInfoDO);
                ResponseUtils.setupSuccessResponse(baseResponse, affectRowNum);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.PLACEMENT_POSITION_INFO_UPDATE;
            }
        });
        return baseResponse;
    }

    @Transactional
    @Override
    public BaseResponse<Integer> finishPlacementOfPosition(PlacementPositionInfoUpdateRequest updateRequest) {

        BizCheckUtil.checkNotNull(updateRequest, "请求不能为空");
        BizCheckUtil.checkNotNull(updateRequest.getIdList(), "idList不能为空");

        for (String id : updateRequest.getIdList()) {
            String adminAreaCode = govOrgService.getAdminAreaCodeOfEmploy(updateRequest.getModifierId());
            PlacementInfoDO alivePlacement = placementInfoService.getAlivePlacement(adminAreaCode);

            PlacementPositionInfoDO positionInfoDO = placementPositionInfoService.get(id);
            BizCheckUtil.checkNotNull(positionInfoDO, "岗位不存在");
            if (Strings.isNotBlank(positionInfoDO.getAuditStatus())) {
                continue;
            }

            positionInfoDO.setStatus(ProcessStatusEnum.SUCCESS.name());
            positionInfoDO.setAuditStatus(ProcessStatusEnum.DEALING.name());
            RequestSetUtils.setModifierInfo(positionInfoDO, updateRequest);
            Integer update = placementPositionInfoService.update(positionInfoDO);


            PlacementBatchDO currentBatch = placementBatchService.getCurrentBatch(alivePlacement.getId());
            if (PlacementBatchTypeEnum.UNIFIED.name().equals(currentBatch.getType())) {
                if (checkIsAllPositionFinished(currentBatch.getId())) {

                    currentBatch.setStatus(ProcessStatusEnum.SUCCESS.name());
                    RequestSetUtils.setModifierInfo(currentBatch, updateRequest);
                    placementBatchService.update(currentBatch);

                    PlacementBatchDO batchInfo = placementBatchService.getByPlacementIdAndType(alivePlacement.getId(), PlacementBatchTypeEnum.OFFLINE.name());

                    List<PlacementSoldierInfoDO> placementSoldierInfoDOS = placementSoldierInfoService.listAllNotRecruitSoldier(alivePlacement.getId());
                    for (PlacementSoldierInfoDO placementSoldierInfoDO : placementSoldierInfoDOS) {
                        placementSoldierInfoDO.setBatchId(batchInfo.getId());
                        placementSoldierInfoDO.setType(batchInfo.getType());
                        placementSoldierInfoService.update(placementSoldierInfoDO);
                    }


                    List<PlacementPositionInfoDTO> lastPosition = listPositionByBatchId(currentBatch.getId());

                    for (PlacementPositionInfoDTO positionInfoDTO : lastPosition) {
                        insertRemainingPosition(positionInfoDTO, batchInfo.getId(), updateRequest);
                    }
                }
            }
        }

        return ResponseUtils.buildSuccessResponse(0);
    }

    @Override
    public BaseResponse<Integer> finishPlacementOfOffline(PlacementPositionInfoUpdateRequest updateRequest) {

        BizCheckUtil.checkNotNull(updateRequest, "请求不能为空");

        String adminAreaCode = govOrgService.getAdminAreaCodeOfEmploy(updateRequest.getModifierId());
        PlacementInfoDO alivePlacement = placementInfoService.getAlivePlacement(adminAreaCode);

        PlacementBatchDO byPlacementIdAndType = placementBatchService.getByPlacementIdAndType(alivePlacement.getId(), PlacementBatchTypeEnum.OFFLINE.name());
        List<PlacementPositionInfoDO> placementPositionInfoDOS = placementPositionInfoService.listByBatchId(byPlacementIdAndType.getId());
        for (PlacementPositionInfoDO placementPositionInfoDO : placementPositionInfoDOS) {
            placementPositionInfoDO.setStatus(ProcessStatusEnum.SUCCESS.name());
            placementPositionInfoDO.setAuditStatus(ProcessStatusEnum.DEALING.name());
            RequestSetUtils.setModifierInfo(placementPositionInfoDO, updateRequest);
            placementPositionInfoService.update(placementPositionInfoDO);
        }
        return ResponseUtils.buildSuccessResponse(0);
    }

    private Boolean checkIsAllPositionFinished(String currentBatchId) {
        List<PlacementPositionInfoDO> placementPositionInfoDOS = placementPositionInfoService.listByBatchId(currentBatchId);
        for (PlacementPositionInfoDO placementPositionInfoDO : placementPositionInfoDOS) {
            if (placementPositionInfoDO.getStatus().equals(ProcessStatusEnum.DEALING.name())) {
                return false;
            }
        }
        return true;
    }

    @Transactional
    @Override
    public BaseResponse<Integer> addThoughTrain(PlacementPositionInfoUpdateRequest updateRequest) {

        BizCheckUtil.checkNotNull(updateRequest);
        BizCheckUtil.checkNotBlank(updateRequest.getId(), "id不能为空");
        BizCheckUtil.checkNotBlank(updateRequest.getThroughTrainType(), "类型不能为空");
        BizCheckUtil.checkNotNull(updateRequest.getQuota(), "岗位数不能为空");

        ThroughTrainTypeEnum byEnumName = ThroughTrainTypeEnum.getByEnumName(updateRequest.getThroughTrainType());
        BizCheckUtil.checkNotNull(byEnumName, "类型错误");

        PlacementPositionInfoDO positionInfoDO = placementPositionInfoService.get(updateRequest.getId());
        BizCheckUtil.checkNotNull(positionInfoDO, "岗位不存在");
        BizCheckUtil.checkIsTrue(positionInfoDO.getType().equals(PlacementBatchTypeEnum.UNIFIED.name()), "只能设置统一安置岗位");
        BizCheckUtil.checkIsTrue(positionInfoDO.getQuota() > 0 && positionInfoDO.getQuota() >= updateRequest.getQuota(), "额度不够");




        PlacementPositionInfoDO ttPosition = new PlacementPositionInfoDO();
        ttPosition.setUnitId(positionInfoDO.getUnitId());
        ttPosition.setUnitName(positionInfoDO.getUnitName());

        PlacementBatchDO placementBatchDO = placementBatchService.get(positionInfoDO.getBatchId());
        PlacementBatchDO ttBatch = placementBatchService.getByPlacementIdAndType(placementBatchDO.getPlacementId(), PlacementBatchTypeEnum.THROUGH_TRAIN.name());
        ttPosition.setBatchId(ttBatch.getId());
        ttPosition.setName(positionInfoDO.getName());
        ttPosition.setType(PlacementBatchTypeEnum.THROUGH_TRAIN.name());
        ttPosition.setQuota(0);
        ttPosition.setStatus(ProcessStatusEnum.DEALING.name());
        ttPosition.setPublished(false);
        ttPosition.setCreatorId(updateRequest.getModifierId());
        ttPosition.setThroughTrainType(byEnumName.name());
        placementPositionInfoService.insert(ttPosition);


        placementPositionInfoService.transferQuota(updateRequest.getId(), ttPosition.getId(), updateRequest.getQuota());
        return ResponseUtils.buildSuccessResponse(0);
    }

    @Override
    public BaseResponse<Integer> publishPosition(PlacementPositionInfoUpdateRequest updateRequest) {

        BizCheckUtil.checkNotNull(updateRequest, "请求参数不能为空");
        BizCheckUtil.checkNotBlank(updateRequest.getId(), "id不能为空");
        BizCheckUtil.checkNotNull(updateRequest.getPublished(), "published 不能为空");
        BizCheckUtil.checkNotNull(updateRequest.getEmployeeId(), "employeeId 不能为空");

        PlacementPositionInfoDO positionInfoDO = placementPositionInfoService.get(updateRequest.getId());
        BizCheckUtil.checkNotNull(positionInfoDO, "岗位不存在");
        if (positionInfoDO.getQuota().equals(0)) {
            return ResponseUtils.buildSuccessResponse(0);
        }
        positionInfoDO.setPublished(updateRequest.getPublished());
        RequestSetUtils.setModifierInfo(positionInfoDO, updateRequest);
        Integer update = placementPositionInfoService.update(positionInfoDO);
        return ResponseUtils.buildSuccessResponse(update);
    }

    @Transactional
    @Override
    public BaseResponse<Integer> publishAllPosition(PlacementPositionInfoUpdateRequest updateRequest) {

        BizCheckUtil.checkNotNull(updateRequest, "请求参数不能为空");
        BizCheckUtil.checkNotNull(updateRequest.getEmployeeId(), "employeeId 不能为空");

        String adminAreaCode = govOrgService.getAdminAreaCodeOfEmploy(updateRequest.getEmployeeId());
        PlacementInfoDO alivePlacement = placementInfoService.getAlivePlacement(adminAreaCode);
        List<PlacementBatchDO> placementBatchDOS = placementBatchService.listByPlacementId(alivePlacement.getId());
        for (PlacementBatchDO placementBatchDO : placementBatchDOS) {
            List<PlacementPositionInfoDO> placementPositionInfoDOS = placementPositionInfoService.listByBatchId(placementBatchDO.getId());
            if (!CollectionUtils.isEmpty(placementPositionInfoDOS)) {
                for (PlacementPositionInfoDO placementPositionInfoDO : placementPositionInfoDOS) {
                    placementPositionInfoDO.setPublished(true);
                    RequestSetUtils.setModifierInfo(placementPositionInfoDO, updateRequest);
                    placementPositionInfoService.update(placementPositionInfoDO);
                }
            }
        }

        return ResponseUtils.buildSuccessResponse(0);
    }

    @Transactional
    @Override
    public BaseResponse<Integer> confirmPosition(PlacementSoldierAspirationResultInsertRequest request) {


        BizCheckUtil.checkNotNull(request, "请求不能为空");
        BizCheckUtil.checkNotBlank(request.getIdCardNo(), "身份证不能为空");
        BizCheckUtil.checkNotBlank(request.getPositionId(), "岗位不能为空");
        BizCheckUtil.checkNotBlank(request.getEmployeeId(), "岗位不能为空");


        PlacementSoldierInfoDO soldierInfo = placementSoldierInfoService.getByIdCardNo(request.getIdCardNo());
        BizCheckUtil.checkNotNull(soldierInfo, "查无此人");
        placementInfoService.checkPlacement(request.getEmployeeId(), soldierInfo.getPlacementId());

        PlacementPositionInfoDO positionInfoDO = placementPositionInfoService.get(request.getPositionId());
        BizCheckUtil.checkNotNull(positionInfoDO, "岗位不存在");

        PlacementBatchDO placementBatchDO = placementBatchService.get(positionInfoDO.getBatchId());

        if (PlacementBatchTypeEnum.UNIFIED.name().equals(placementBatchDO.getType())) {
            BizCheckUtil.checkNotNull(soldierInfo.getExamScore(), "统一安置，请先导入考试分");
        }

        List<PlacementSoldierAspirationDO> aspirationDOS = placementSoldierAspirationService.listByIdCardNo(request.getIdCardNo());
        BizCheckUtil.checkIsTrue(!CollectionUtils.isEmpty(aspirationDOS), "还未填报");
        Set<String> collect = aspirationDOS.stream().map(s -> s.getPositionId()).collect(Collectors.toSet());
        BizCheckUtil.checkIsTrue(collect.contains(request.getPositionId()), "未填报此岗位");

        PlacementSoldierAspirationDO thisAsp = getAsp(aspirationDOS, request.getPositionId());
        thisAsp.setConfirmAttachment(request.getConfirmAttachment());
        thisAsp.setConfirmRemark(request.getConfirmRemark());
        placementSoldierAspirationService.update(thisAsp);

        PlacementSoldierAspirationResultDO resultDO = placementSoldierAspirationResultService.getByIdCardNo(request.getIdCardNo());
        BizCheckUtil.checkIsTrue(resultDO == null, "已填报");

        Integer alreadyNum = placementSoldierAspirationResultService.countByPositionId(request.getPositionId());
        BizCheckUtil.checkIsTrue(alreadyNum < positionInfoDO.getQuota(), "岗位已满");
        resultDO = new PlacementSoldierAspirationResultDO();
        resultDO.setPlacementId(soldierInfo.getPlacementId());
        resultDO.setBatchId(positionInfoDO.getBatchId());
        resultDO.setSoldierId(soldierInfo.getSoldierId());
        resultDO.setIdCardNo(soldierInfo.getIdCardNo());
        resultDO.setRealName(soldierInfo.getRealName());
        resultDO.setPositionId(request.getPositionId());
        resultDO.setStatus(PlacementAspirationResultStatusEnum.SUCCESS.name());
        placementSoldierAspirationResultService.insert(resultDO);
        log.info("志愿匹配成功：{}", resultDO);
        return ResponseUtils.buildSuccessResponse(0);
    }

    private PlacementSoldierAspirationDO getAsp(List<PlacementSoldierAspirationDO> aspirationDOS, String positionId) {
        for (PlacementSoldierAspirationDO aspirationDO : aspirationDOS) {
            if (positionId.equals(aspirationDO.getPositionId())) {
                return aspirationDO;
            }
        }

        return null;
    }

    @Transactional
    @Override
    public BaseResponse<Integer> addAspiration(PlacementSoldierAspirationResultInsertRequest request) {


        BizCheckUtil.checkNotNull(request, "请求参数不能为空");
        BizCheckUtil.checkNotBlank(request.getPositionId(), "岗位不能为空");
        String idCardNo = request.getIdCardNo();
        BizCheckUtil.checkNotBlank(idCardNo, "身份证不能为空");

        PlacementSoldierInfoDO soldierInfoDO = placementSoldierInfoService.getByIdCardNo(idCardNo);
        BizCheckUtil.checkNotNull(soldierInfoDO, "查无此人");

        PlacementPositionInfoDO positionInfoDO = placementPositionInfoService.get(request.getPositionId());
        BizCheckUtil.checkNotNull(positionInfoDO, "岗位不存在");
        BizCheckUtil.checkIsTrue(!positionInfoDO.getStatus().equals(ProcessStatusEnum.SUCCESS.name()), "该岗位已经完成安置！ ");
        PlacementBatchDO placementBatchDO = placementBatchService.get(positionInfoDO.getBatchId());

        if (PlacementBatchTypeEnum.UNIFIED.name().equals(placementBatchDO.getType())) {
            BizCheckUtil.checkNotNull(soldierInfoDO.getExamScore(), "统一安置，请先导入考试分");
        }

        PlacementSoldierAspirationResultDO ar = placementSoldierAspirationResultService.getByIdCardNo(idCardNo);
        BizCheckUtil.checkIsTrue(ar == null, "已填报");

        Integer integer = placementSoldierAspirationResultService.countByPositionId(positionInfoDO.getId());
        BizCheckUtil.checkIsTrue(integer < positionInfoDO.getQuota(), "填报已满");


        List<PlacementSoldierAspirationDO> aspirationDOS = placementSoldierAspirationService.listByIdCardNo(soldierInfoDO.getIdCardNo());
        if (CollectionUtils.isEmpty(aspirationDOS)) {
            addAp(request, soldierInfoDO, positionInfoDO.getBatchId());
        } else {
            if (!checkHasAspiration(aspirationDOS, request.getPositionId())) {
                addAp(request, soldierInfoDO, positionInfoDO.getBatchId());
                for (PlacementSoldierAspirationDO aspirationDO : aspirationDOS) {
                    aspirationDO.setSeqNo(aspirationDO.getSeqNo() + 1);
                    placementSoldierAspirationService.update(aspirationDO);
                }
            }
        }

        PlacementSoldierAspirationResultDO resultDO = new PlacementSoldierAspirationResultDO();
        resultDO.setPlacementId(soldierInfoDO.getPlacementId());
        resultDO.setBatchId(positionInfoDO.getBatchId());
        resultDO.setSoldierId(soldierInfoDO.getSoldierId());
        resultDO.setIdCardNo(soldierInfoDO.getIdCardNo());
        resultDO.setRealName(soldierInfoDO.getRealName());
        resultDO.setPositionId(request.getPositionId());
        resultDO.setOfflineType(request.getOfflineType());
        resultDO.setStatus(PlacementAspirationResultStatusEnum.SUCCESS.name());

        RequestSetUtils.setCreatorInfo(resultDO, request);
        Integer insert = placementSoldierAspirationResultService.insert(resultDO);

        soldierInfoDO.setBatchId(positionInfoDO.getBatchId());
        soldierInfoDO.setType(positionInfoDO.getType());
        soldierInfoDO.setPlacementPositionId(positionInfoDO.getId());
        soldierInfoDO.setPlacementPosition(positionInfoDO.getUnitName() + "-" + positionInfoDO.getName());
        soldierInfoDO.setPlacementType(positionInfoDO.getType());
        placementSoldierInfoService.update(soldierInfoDO);

        return ResponseUtils.buildSuccessResponse(insert);
    }

    private void addAp(PlacementSoldierAspirationResultInsertRequest request, PlacementSoldierInfoDO soldierInfoDO, String batchId) {
        PlacementSoldierAspirationDO aspirationDO = new PlacementSoldierAspirationDO();
        aspirationDO.setPlacementId(soldierInfoDO.getPlacementId());
        aspirationDO.setBatchId(batchId);
        aspirationDO.setSoldierId(soldierInfoDO.getSoldierId());
        aspirationDO.setIdCardNo(soldierInfoDO.getIdCardNo());
        aspirationDO.setRealName(soldierInfoDO.getRealName());
        aspirationDO.setPositionId(request.getPositionId());
        aspirationDO.setSeqNo(0);
        aspirationDO.setAttachment(request.getAttachment());
        aspirationDO.setRemark(request.getRemark());
        aspirationDO.setOfflineType(request.getOfflineType());
        aspirationDO.setConfirmAttachment(request.getConfirmAttachment());
        aspirationDO.setAttachment(request.getAttachment());

        aspirationDO.setStatus(ThroughTrainProcessEnum.SUCCESS.name());
        placementSoldierAspirationService.insert(aspirationDO);
    }

    private boolean checkHasAspiration(List<PlacementSoldierAspirationDO> aspirationDOS, String positionId) {
        for (PlacementSoldierAspirationDO aspirationDO : aspirationDOS) {
            if (positionId.equals(aspirationDO.getPositionId())) {
                return true;
            }
        }
        return false;
    }

    @Transactional
    @Override
    public BaseResponse<Integer> geneNextBatchPosition(PlacementPositionInfoUpdateRequest request) {

        BizCheckUtil.checkNotNull(request, "逻辑删除PlacementPositionInfo的请求参数不能为空");
        BizCheckUtil.checkNotBlank(request.getEmployeeId(), "id不能为空");

        String adminAreaCode = govOrgService.getAdminAreaCodeOfEmploy(request.getEmployeeId());
        PlacementInfoDO alivePlacement = placementInfoService.getAlivePlacement(adminAreaCode);
        List<PlacementBatchDO> placementBatchDOS = placementBatchService.listByPlacementId(alivePlacement.getId());
        BizCheckUtil.checkIsTrue(!CollectionUtils.isEmpty(placementBatchDOS), "暂无批次");
        String lastBatchId = getLastBatchId(placementBatchDOS);
        String currentBatch = getCurrentBatch(placementBatchDOS);

        List<PlacementPositionInfoDTO> lastPosition = listPositionByBatchId(lastBatchId);
        for (PlacementPositionInfoDTO positionInfoDTO : lastPosition) {
            insertRemainingPosition(positionInfoDTO, currentBatch, request);
        }

        return ResponseUtils.buildSuccessResponse(0);
    }

    private void insertRemainingPosition(PlacementPositionInfoDTO positionInfoDTO, String currentBatchId, PlacementPositionInfoUpdateRequest request) {
        PlacementPositionInfoDO existedPosition = placementPositionInfoService.getByBatchIdAndUnitAndName(currentBatchId, positionInfoDTO.getUnitId(), positionInfoDTO.getName());
        if (existedPosition != null) {
            int existedQuota = positionInfoDTO.getQuota() - positionInfoDTO.getUsed();
            existedPosition.setQuota(existedPosition.getQuota() + existedQuota);
            existedPosition.setPublished(false);
            placementPositionInfoService.update(existedPosition);
            return;
        }

        PlacementPositionInfoDO infoDO = new PlacementPositionInfoDO();
        BeanUtils.copyProperties(positionInfoDTO, infoDO);

        PlacementBatchDO placementBatchDO = placementBatchService.get(currentBatchId);
        infoDO.setPublished(false);
        infoDO.setBatchId(currentBatchId);
        infoDO.setType(placementBatchDO.getType());
        infoDO.setQuota(positionInfoDTO.getQuota() - positionInfoDTO.getUsed());
        infoDO.setCreatorType(request.getModifierType());
        infoDO.setCreatorId(request.getModifierId());
        infoDO.setStatus(ProcessStatusEnum.DEALING.name());
        infoDO.setAuditStatus("");
        infoDO.setPublished(false);
        placementPositionInfoService.insert(infoDO);
    }

    private String getCurrentBatch(List<PlacementBatchDO> placementBatchDOS) {
        for (int i = 0; i < placementBatchDOS.size(); i++) {
            PlacementBatchDO placementBatchDO = placementBatchDOS.get(i);
            if (ProcessStatusEnum.DEALING.name().equals(placementBatchDO.getStatus())) {
                String id = placementBatchDOS.get(i).getId();
                List<PlacementPositionInfoDO> placementPositionInfoDOS = placementPositionInfoService.listByBatchId(id);
                BizCheckUtil.checkIsTrue(CollectionUtils.isEmpty(placementPositionInfoDOS), "已存在");
                return id;
            }
        }
        throw new BizException(ErrorCodeEnum.ILLEGAL_PARAM, "无批次");
    }

    private String getLastBatchId(List<PlacementBatchDO> placementBatchDOS) {
        for (int i = 0; i < placementBatchDOS.size(); i++) {
            PlacementBatchDO placementBatchDO = placementBatchDOS.get(i);
            if (ProcessStatusEnum.DEALING.name().equals(placementBatchDO.getStatus())) {
                BizCheckUtil.checkIsTrue(i != 0, "无之前批次");
                return placementBatchDOS.get(i - 1).getId();
            }
        }
        throw new BizException(ErrorCodeEnum.ILLEGAL_PARAM, "暂无进行中的批次");
    }


    @Override
    public BaseResponse<Integer> deletePlacementPositionInfo(final BaseDeleteRequest deleteRequest) {

        final BaseResponse<Integer> baseResponse = new BaseResponse<>();
        serviceTemplate.execute(transactionTemplate, baseResponse, new ServiceCallback() {
            @Override
            public void check() {
                BizCheckUtil.checkNotNull(deleteRequest, "逻辑删除PlacementPositionInfo的请求参数不能为空");
                BizCheckUtil.checkNotBlank((String) deleteRequest.getId(), "id不能为空");
                BizCheckUtil.checkNotBlank(deleteRequest.getModifierType(), "操作人类型不能为空");
                BizCheckUtil.checkNotBlank((String) deleteRequest.getModifierId(), "操作人不能为空");
            }

            @Override
            public void executeService() {
                final Integer affectRowNum = placementPositionInfoService.delete((String) deleteRequest.getId(), deleteRequest.getModifierType(), (String) deleteRequest.getModifierId());
                ResponseUtils.setupSuccessResponse(baseResponse, affectRowNum);
            }

            @Override
            public ScenarioCodeEnum getScenarioEnum() {
                return ScenarioCodeEnum.PLACEMENT_POSITION_INFO_DELETE_LOGICALLY;
            }
        });
        return baseResponse;
    }

    @Override
    public List<PlacementPositionInfoDTO> listPositionByBatchId(String batchId) {
        PlacementPositionInfoBSearcher bSearcher = new PlacementPositionInfoBSearcher(1, Integer.MAX_VALUE);
        bSearcher.setBatchId(batchId);
        List<PlacementPositionInfoDO> search = placementPositionInfoService.search(bSearcher);
        List<PlacementPositionInfoDTO> placementPositionInfoDTOList = PlacementPositionInfoProviderConverter.convertResponseDOList2DTOList(search);

        List<PlacementSoldierAspirationResultDO> list = placementSoldierAspirationResultService.listByBatchId(batchId);
        clearFullPosition(placementPositionInfoDTOList, list);
        return placementPositionInfoDTOList;
    }

    @Override
    public BaseResponse<Integer> checkPositionViewAuth(final BaseGetRequest baseGetRequest) {

        BizCheckUtil.checkNotNull(baseGetRequest, "获取单条PlacementPositionInfo的请求参数不能为空");
        BizCheckUtil.checkNotBlank((String) baseGetRequest.getId(), "id不能为空");

        final PlacementPositionInfoDO placementPositionInfoDO = placementPositionInfoService.get((String) baseGetRequest.getId());
        PlacementBatchDO placementBatchDO = placementBatchService.get(placementPositionInfoDO.getBatchId());
        if (PlacementBatchTypeEnum.UNIFIED.name().equals(placementBatchDO.getType())) {
            String year = DateUtil.format(new Date(), "yyyy");
            PlacementInfoDO placementInfoDO = placementInfoService.get(placementBatchDO.getPlacementId());
            String prefix = placementInfoDO.getAdminAreaCode() + year;

            CommonDataDictDO pw1 = commonDataDictService.getByCode(prefix + "pw1");
            BizCheckUtil.checkNotNull(pw1, "还未设置密码");


            BizCheckUtil.checkIsTrue(placementBatchDO.getApplyEndDatetime().before(new Date()), "还未到填报截止时间");
            if (Boolean.TRUE.equals(pw1.getUsed())) {
                return ResponseUtils.buildSuccessResponse(0);
            }
            return ResponseUtils.buildSuccessResponse(1);
        }

        return ResponseUtils.buildSuccessResponse(0);
    }

    private String getLevel(String resourceCode) {
        Matcher matcher = authPattern.matcher(resourceCode);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return null;
    }

    @Override
    public BaseResponse<Integer> initPws(CommonDataDictInsertRequest request) {

        BizCheckUtil.checkNotBlank(request.getPw1(), "请输入密码");
        BizCheckUtil.checkNotBlank(request.getPw2(), "请输入密码");
        BizCheckUtil.checkNotBlank(request.getPw3(), "请输入密码");

        String adminAreaCode = govOrgService.getAdminAreaCodeOfEmploy(request.getEmployeeId());
        String year = DateUtil.format(new Date(), "yyyy");
        String prefix = adminAreaCode + year;

        CommonDataDictDO dataDictDO = commonDataDictService.getByCode(prefix + "pw1");
        BizCheckUtil.checkIsNull(dataDictDO, "密码已存在");

        CommonDataDictDO d1 = new CommonDataDictDO();
        d1.setModuleName("PLACEMENT");
        d1.setCode(prefix + "pw1");
        d1.setValue(PasswordUtils.encode(request.getPw1(), ""));
        commonDataDictService.insert(d1);

        CommonDataDictDO d2 = new CommonDataDictDO();
        d2.setModuleName("PLACEMENT");
        d2.setCode(prefix + "pw2");
        d2.setValue(PasswordUtils.encode(request.getPw2(), ""));
        commonDataDictService.insert(d2);

        CommonDataDictDO d3 = new CommonDataDictDO();
        d3.setModuleName("PLACEMENT");
        d3.setCode(prefix + "pw3");
        d3.setValue(PasswordUtils.encode(request.getPw3(), ""));
        commonDataDictService.insert(d3);

        return ResponseUtils.buildSuccessResponse(0);
    }

    @Override
    public BaseResponse<Integer> deletePws(CommonDataDictInsertRequest request) {

        BizCheckUtil.checkNotBlank(request.getPw1(), "请输入密码");
        BizCheckUtil.checkNotBlank(request.getPw2(), "请输入密码");
        BizCheckUtil.checkNotBlank(request.getPw3(), "请输入密码");

        String adminAreaCode = govOrgService.getAdminAreaCodeOfEmploy(request.getEmployeeId());
        String year = DateUtil.format(new Date(), "yyyy");
        String prefix = adminAreaCode + year;

        CommonDataDictDO pw1 = commonDataDictService.getByCode(prefix + "pw1");
        CommonDataDictDO pw2 = commonDataDictService.getByCode(prefix + "pw2");
        CommonDataDictDO pw3 = commonDataDictService.getByCode(prefix + "pw3");
        BizCheckUtil.checkNotNull(pw1, "密码还未设置");
        BizCheckUtil.checkIsTrue(pw1.getValue().equals(PasswordUtils.encode(request.getPw1(), "")), "密码不一致");
        BizCheckUtil.checkIsTrue(pw2.getValue().equals(PasswordUtils.encode(request.getPw2(), "")), "密码不一致");
        BizCheckUtil.checkIsTrue(pw3.getValue().equals(PasswordUtils.encode(request.getPw3(), "")), "密码不一致");

        commonDataDictService.deleteByCode(pw1.getId(), UserTypeEnum.GOV_EMPLOYEE.name(), request.getEmployeeId());
        commonDataDictService.deleteByCode(pw2.getId(), UserTypeEnum.GOV_EMPLOYEE.name(), request.getEmployeeId());
        commonDataDictService.deleteByCode(pw3.getId(), UserTypeEnum.GOV_EMPLOYEE.name(), request.getEmployeeId());

        return ResponseUtils.buildSuccessResponse(0);
    }

    @Transactional
    @Override
    public BaseResponse<Integer> checkPws(CommonDataDictInsertRequest request) {

        BizCheckUtil.checkNotBlank(request.getPw1(), "请输入密码");
        BizCheckUtil.checkNotBlank(request.getPw2(), "请输入密码");
        BizCheckUtil.checkNotBlank(request.getPw3(), "请输入密码");

        String adminAreaCode = govOrgService.getAdminAreaCodeOfEmploy(request.getEmployeeId());
        String year = DateUtil.format(new Date(), "yyyy");
        String prefix = adminAreaCode + year;

        CommonDataDictDO pw1 = commonDataDictService.getByCode(prefix + "pw1");
        CommonDataDictDO pw2 = commonDataDictService.getByCode(prefix + "pw2");
        CommonDataDictDO pw3 = commonDataDictService.getByCode(prefix + "pw3");
        BizCheckUtil.checkNotNull(pw1, "密码还未设置");
        BizCheckUtil.checkIsTrue(pw1.getValue().equals(PasswordUtils.encode(request.getPw1(), "")), "密码不一致");
        BizCheckUtil.checkIsTrue(pw2.getValue().equals(PasswordUtils.encode(request.getPw2(), "")), "密码不一致");
        BizCheckUtil.checkIsTrue(pw3.getValue().equals(PasswordUtils.encode(request.getPw3(), "")), "密码不一致");

        commonDataDictService.setUsed(prefix + "pw1");
        commonDataDictService.setUsed(prefix + "pw2");
        commonDataDictService.setUsed(prefix + "pw3");
        return ResponseUtils.buildSuccessResponse(0);
    }























}
